// License Notification
//======================================================
// Copyright (c) 2010 Channel Intelligence Inc.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// ======================================================




using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Linq;
using System.Drawing;
using CIP4.Common;
using CIP4.Item;

namespace CIP4.RulesEngine
{
    public class ItemDataPacketType : IDataPacketType
    {
        object _Value;

        public ISerializerType Serializer { get; set; }

        public void Bind(string rootName, object value)
        {
            if (!Serializer.TargetType.IsAssignableFrom(value.GetType()))
                throw new ArgumentException(string.Format("Cannot bind an object of type {0} to this data packet as it has a serializer of type {1}", value.GetType().Name, Serializer.SerializerType.Name));
            _Value = value;
        }

        public LoggerDelegate Logger { get; set; }

        public ActionUsageEnum PacketUsage { get; set; }

        private RulesEngineOperationsType m_Operations;
        public IRulesEngineOperationsType Operations
        {
            get
            {
                if (m_Operations == null)
                    m_Operations = new RulesEngineOperationsType(this);
                return m_Operations;
            }
            set { m_Operations = (RulesEngineOperationsType)value; }
        }

        public object OtherData;

        private Dictionary<string, List<string>> m_UniqueValues;
        public Dictionary<string, List<string>> UniqueValues
        {
            get
            {
                if (m_UniqueValues == null)
                    m_UniqueValues = new Dictionary<string, List<string>>();
                return m_UniqueValues;
            }
            set
            {
                m_UniqueValues = value;
            }
        }

        public GetValueDelegate GetValue { get; set; }

        public SetValueDelegate SetValue { get; set; }

        public IPacketStatsType PacketStats { get; set; }

        private Dictionary<string, object> m_Parameters;
        public Dictionary<string, object> Parameters
        {
            get
            {
                if (m_Parameters == null)
                    m_Parameters = new Dictionary<string, object>();
                return m_Parameters;
            }
        }

        public ItemDataPacketType()
        {
            Operations = new RulesEngineOperationsType(this);
            Reset();
        }

        public object GetNamedValue(string name)
        {
            return Serializer.GetValueForPath(_Value, name);
        }

        /// <summary>
        /// This must be called once for each invocation of an Action
        /// to clear out the information used by the previous invocation
        /// </summary>
        public void Reset()
        {
        }

        public override string ToString()
        {
            return base.ToString();
        }
    }

    public class PacketStatsType : IPacketStatsType
    {
        private long[] m_BooleanOperatorsCount;

        public long[] BooleanOperatorsCount
        {
            get { return m_BooleanOperatorsCount; }
            set { m_BooleanOperatorsCount = value; }
        }
        private long[] m_LogicalOperatorsCount;

        public long[] LogicalOperatorsCount
        {
            get { return m_LogicalOperatorsCount; }
            set { m_LogicalOperatorsCount = value; }
        }
        private long[] m_StringOperatorsCount;

        public long[] StringOperatorsCount
        {
            get { return m_StringOperatorsCount; }
            set { m_StringOperatorsCount = value; }
        }
        private long[] m_ArithmeticOperatorsCount;

        public long[] ArithmeticOperatorsCount
        {
            get { return m_ArithmeticOperatorsCount; }
            set { m_ArithmeticOperatorsCount = value; }
        }
        private long[] m_ActionOperatorsCount;

        public long[] ActionOperatorsCount
        {
            get { return m_ActionOperatorsCount; }
            set { m_ActionOperatorsCount = value; }
        }
        private long[] m_DateTimeOperatorsCount;

        public long[] DateTimeOperatorsCount
        {
            get { return m_DateTimeOperatorsCount; }
            set { m_DateTimeOperatorsCount = value; }
        }
        private long m_TestedObjectCount;

        public long TestedObjectCount
        {
            get { return m_TestedObjectCount; }
            set { m_TestedObjectCount = value; }
        }
        private long m_ActedOnObjectCount;

        public long ActedOnObjectCount
        {
            get { return m_ActedOnObjectCount; }
            set { m_ActedOnObjectCount = value; }
        }
        public PacketStatsType()
        {
            m_BooleanOperatorsCount = new long[(int)BooleanOperatorsEnum.INVALIDOP];
            m_LogicalOperatorsCount = new long[(int)LogicalOperatorsEnum.INVALIDOP];
            m_StringOperatorsCount = new long[(int)StringOperatorsEnum.INVALIDOP];
            m_ArithmeticOperatorsCount = new long[(int)ArithmeticOperatorsEnum.INVALIDOP];
            m_DateTimeOperatorsCount = new long[(int)DateTimeOperatorsEnum.INVALIDOP];
            m_ActionOperatorsCount = new long[(int)ActionOperatorEnum.INVALIDOP];
        }
        public override string ToString()
        {
            System.IO.StringWriter swrtr = new System.IO.StringWriter();
            swrtr.WriteLine("{0} objects tested", TestedObjectCount.ToString());
            swrtr.WriteLine("{0} objects acted on", ActedOnObjectCount.ToString());
            for (long i = 0; i < (int)BooleanOperatorsEnum.INVALIDOP; i++)
                if (m_BooleanOperatorsCount[i] > 0)
                    swrtr.WriteLine(string.Format("{0} used {1} times", ((BooleanOperatorsEnum)i).ToString(), m_BooleanOperatorsCount[i]));
            for (long i = 0; i < (int)LogicalOperatorsEnum.INVALIDOP; i++)
                if (m_LogicalOperatorsCount[i] > 0)
                    swrtr.WriteLine(string.Format("{0} used {1} times", ((LogicalOperatorsEnum)i).ToString(), m_LogicalOperatorsCount[i]));
            for (long i = 0; i < (int)StringOperatorsEnum.INVALIDOP; i++)
                if (StringOperatorsCount[i] > 0)
                    swrtr.WriteLine(string.Format("{0} used {1} times", ((StringOperatorsEnum)i).ToString(), StringOperatorsCount[i]));
            for (long i = 0; i < (int)ArithmeticOperatorsEnum.INVALIDOP; i++)
                if (ArithmeticOperatorsCount[i] > 0)
                    swrtr.WriteLine(string.Format("{0} used {1} times", ((ArithmeticOperatorsEnum)i).ToString(), ArithmeticOperatorsCount[i]));
            for (long i = 0; i < (int)DateTimeOperatorsEnum.INVALIDOP; i++)
                if (DateTimeOperatorsCount[i] > 0)
                    swrtr.WriteLine(string.Format("{0} used {1} times", ((DateTimeOperatorsEnum)i).ToString(), DateTimeOperatorsCount[i]));
            for (long i = 0; i < (int)ActionOperatorEnum.INVALIDOP; i++)
                if (ActionOperatorsCount[i] > 0)
                    swrtr.WriteLine(string.Format("{0} used {1} times", ((ActionOperatorEnum)i).ToString(), ActionOperatorsCount[i]));
            return swrtr.ToString();
        }
    }
}